home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OWLSRC.PAK / MODULE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  17.1 KB  |  709 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.24  $
  6. //
  7. // Implementation of class TModule. TModule defines the base behavior for
  8. // OWL libraries and applications.
  9. //----------------------------------------------------------------------------
  10. #pragma hdrignore SECTION
  11. #include <owl/pch.h>
  12. #if !defined(OWL_MODULE_H)
  13. # include <owl/module.h>
  14. #endif
  15. #if !defined(OWL_APPDICT_H)
  16. # include <owl/appdict.h>
  17. #endif
  18. #if !defined(OWL_APPLICAT_H)
  19. # include <owl/applicat.h>
  20. #endif
  21. #if !defined(CLASSLIB_POINTER_H)
  22. # include <classlib/pointer.h>
  23. #endif
  24. #include <stdio.h>
  25. #if defined(BI_PLAT_WIN32)
  26. # include <winnls.h>
  27. #endif
  28.  
  29. extern 
  30. uint _OWLDATA GetWindowPtrMsgId;   // Defined in APPLICAT.CPP
  31.  
  32. OWL_DIAGINFO;
  33. DIAG_DECLARE_GROUP(OwlApp);        // General Application diagnostic group
  34.  
  35. #if !defined(SECTION) || SECTION == 1
  36.  
  37. //----------------------------------------------------------------------------
  38.  
  39. //
  40. // Implementation of Constructors for a TModule object
  41. //
  42.  
  43. //
  44. // Construct a TModule that is an alias for a DLL. TModule will load & free
  45. // the DLL if "shouldLoad" is true. If "shouldLoad" is false, then the Handle
  46. // must be set some time later using InitModule().
  47. // "mustLoad" determines if a load failure should cause an exception throw
  48. //
  49. TModule::TModule(const char far* name, bool shouldLoad, bool mustLoad)
  50.         :Name(0)
  51. {
  52.   if (shouldLoad) {
  53.     TErrorMode loadMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  54.     Handle = ::LoadLibrary(name);
  55.     if (Handle <= HINSTANCE(HINSTANCE_ERROR) && mustLoad) {
  56.       TRACEX(OwlApp, 0, "Unable to load DLL '" << string(name) << '\'');
  57.       TXInvalidModule::Raise(name);  
  58.     }
  59.   }
  60.   else {
  61.     Handle = 0;
  62.   }
  63.  
  64.   ShouldFree = shouldLoad;
  65.   SetName(name);
  66. #if defined(OWL1_COMPAT)
  67.   lpCmdLine = 0;
  68. #endif
  69. }
  70.  
  71. //
  72. // Construct a TModule that is an alias for an already loaded DLL or program
  73. // with an Handle available. Name is optional & can be 0. No cmdLine is
  74. // setup
  75. //
  76. TModule::TModule(const char far* name, HINSTANCE hInstance)
  77.         :Name(0)
  78. {
  79.   PRECONDITION(hInstance > HINSTANCE(HINSTANCE_ERROR));
  80.   Handle = hInstance;
  81.   ShouldFree = false;
  82.   SetName(name);
  83. #if defined(OWL1_COMPAT)
  84.   lpCmdLine = 0;
  85. #endif
  86. }
  87.  
  88. //
  89. // Construct a TModule for an Owl Program via TApplication. InitModule is
  90. // called from here to initialize Handle & the CmdLine
  91. //
  92. TModule::TModule(const char far* name, HINSTANCE hInstance,
  93.                  const char far* cmdLine) : Name(0)
  94. {
  95.   Handle = 0;
  96.   ShouldFree = false;
  97.   SetName(name);
  98. #if defined(OWL1_COMPAT)
  99.   lpCmdLine = 0;
  100. #endif
  101.   if (hInstance)
  102.     InitModule(hInstance, cmdLine);
  103. }
  104.  
  105. //
  106. // Destruct a TModule, freeing the instance if appropriate, and deleting
  107. // new'd strings
  108. //
  109. TModule::~TModule()
  110. {
  111.   if (ShouldFree && Handle > HINSTANCE(HINSTANCE_ERROR))
  112.     ::FreeLibrary(Handle);
  113.   delete[] Name;
  114. #if defined(OWL1_COMPAT)
  115.   delete[] lpCmdLine;
  116. #endif
  117. }
  118.  
  119. //
  120. //
  121. //
  122. void
  123. TModule::SetName(const char far* name)
  124. {
  125.   delete[] Name;
  126.   TAPointer<char> moduleName;
  127.   if (Handle > HINSTANCE(HINSTANCE_ERROR) && !name) {
  128.     moduleName = new char[_MAX_PATH];
  129.     if (GetModuleFileName(moduleName, _MAX_PATH))
  130.       name = moduleName;
  131.   }
  132.   Name = strnewdup(name);
  133. }
  134.  
  135. //
  136. // Perform initialization of modules cmd line copy, and get proc
  137. // instance handles for the standard procs.
  138. //
  139. void
  140. #if defined(OWL1_COMPAT)
  141. TModule::InitModule(HINSTANCE hInstance, const char far* cmdLine)
  142. #else
  143. TModule::InitModule(HINSTANCE hInstance, const char far*)
  144. #endif
  145. {
  146.   SetHandle(hInstance);
  147.  
  148. #if (__BORLANDC__ < 0x0500) && defined(BI_PLAT_WIN32)
  149.   // This used to be a problem, but now the RTL takes care of this.
  150.   // Win32 prepends the full application path to the command line arguments
  151.   // skip over this "extra" argument for 16-bit compatibility
  152.   // _argc and _argv do the correct processing, _argv[0] being the pathname
  153.   //
  154.   if (cmdLine)
  155.     while (*cmdLine && *cmdLine++ != ' ')
  156.       ;
  157. #endif
  158.  
  159. #if defined(OWL1_COMPAT)
  160.   if (cmdLine)
  161.     lpCmdLine = strnewdup(cmdLine);
  162. #endif
  163.  
  164.   // Register a system-wide "GetWindowPtr" message as GetWindowPtr(_hInstance)
  165.   // Each running copy of ObjectWindows will get a unique message Id
  166.   //
  167.   if (!GetWindowPtrMsgId) {
  168.     const char msgTemplate[] = "GetWindowPtr(%X)";
  169.     char msgName[sizeof(msgTemplate) + 8];
  170.     sprintf(msgName, msgTemplate, unsigned(_hInstance));
  171.     GetWindowPtrMsgId = ::RegisterWindowMessage(msgName);
  172.     CHECK(GetWindowPtrMsgId);
  173.   }
  174. }
  175.  
  176. //
  177. // Replaceable exception handler; may be redefined to process OWL exceptions
  178. // if canResume is false, then the user doesn't have the option of ignoring
  179. //
  180. int
  181. TModule::Error(xmsg& x, unsigned captionResId, unsigned promptResId)
  182. {
  183.   char cbuf[80];
  184.   char pbuf[80];
  185.  
  186.   if (!captionResId)
  187.     captionResId = IDS_UNHANDLEDXMSG;
  188.   return HandleGlobalException(x,
  189.     LoadString(captionResId, cbuf, sizeof(cbuf)) ? cbuf : 0,
  190.     promptResId ?
  191.       (LoadString(promptResId, pbuf, sizeof(pbuf)) ? pbuf : "OK to Resume?")
  192.       : 0);
  193. }
  194.  
  195. //
  196. // Set the instance handle for a module that does not yet have one. Cannot
  197. // be called on a module that already has an instance handle.
  198. //
  199. void
  200. TModule::SetHandle(HINSTANCE hInstance)
  201. {
  202.   PRECONDITION(!ShouldFree && !Handle);
  203.   Handle = hInstance;
  204. }
  205.  
  206. //
  207. // LoadString replacements which do not generated debug warning output
  208. //
  209. #if defined(BI_PLAT_WIN32)
  210.  typedef WCHAR* TResText;
  211.  typedef WCHAR* TResCount;
  212. #else
  213.  typedef char far* TResText;
  214.  typedef uint8 far* TResCount;
  215. #endif
  216.  
  217. //
  218. // Wrapper for loading a string resource.
  219. //
  220. int
  221. TModule::LoadString(uint id, char far* buf, int bufSize) const
  222. {
  223.   uint len = 0;
  224.   HRSRC     resHdl;
  225.   HGLOBAL   glbHdl;
  226.   TResText  resData;
  227.  
  228.   if ((resHdl = FindResource(id/16+1, RT_STRING)) != 0
  229.    && (glbHdl = LoadResource(resHdl)) != 0) {
  230.     if ((resData = (TResText)LockResource(glbHdl)) != 0) {
  231.       int cnt;
  232.       for (cnt = id % 16; len = *(TResCount)resData++, cnt--; resData += len)
  233.         ;
  234.       if (len != 0) {
  235. #if defined(BI_PLAT_WIN32)
  236.         len = ::WideCharToMultiByte(CP_ACP, 0, resData, len, buf, bufSize, 0, 0);
  237.         if (len > 0)
  238.           buf[len] = 0;
  239. #else
  240.         if (len >= uint(bufSize))
  241.           len = bufSize-1;
  242.         for (cnt = len; cnt--; *buf++ = (char)*resData++)
  243.           ;
  244.         *buf = 0;
  245. #endif
  246.       }
  247.       UnlockResource(glbHdl);
  248.     }
  249.     FreeResource(glbHdl);
  250.     if (len)
  251.       return len;
  252.   }
  253.  
  254.   if (::Module != this)                   // look in OWL module if different
  255.     return ::Module->LoadString(id, buf, bufSize);
  256.  
  257.   if (bufSize)
  258.     *buf = 0;  // make empty string just in case caller doesn't check return
  259.   return 0;    // indicate string not found
  260. }
  261.  
  262. //
  263. // Wrapper for loading a string resource.
  264. // Returns a string object.
  265. //
  266. string
  267. TModule::LoadString(uint id) const
  268. {
  269.   uint len = 0;
  270.   HRSRC     resHdl;
  271.   HGLOBAL   glbHdl;
  272.   TResText  resData;
  273.   string    retString;
  274.  
  275.   if ((resHdl = FindResource(id/16+1, RT_STRING)) != 0
  276.    && (glbHdl = LoadResource(resHdl)) != 0) {
  277.     if ((resData = (TResText)LockResource(glbHdl)) != 0) {
  278.       int cnt;
  279.       for (cnt = id % 16; len = *(TResCount)resData++, cnt--; resData += len)
  280.         ;
  281.       if (len != 0) {
  282. #if (0) // This is dangerous unless string is changed to handle non-terminated
  283.         // char arrays
  284.         //
  285.         retString.append(resData, 0, len);
  286. #else
  287. # if defined(BI_PLAT_WIN32)
  288.         int n = ::WideCharToMultiByte(CP_ACP, 0, resData, len, 0, 0, 0, 0);
  289.         TAPointer<char> buf = new char[n+1];
  290.         len = ::WideCharToMultiByte(CP_ACP, 0, resData, len, buf, n+1, 0, 0);
  291.   #if   0
  292.         retString.resize(len+1);
  293.         uint i;
  294.         for (i = 0; i < len; i++)
  295.           retString[i] = (char)buf[i];
  296.         retString[i] = 0;
  297.   #else
  298.         // The string object does not need the terminating null of C-strings
  299.         //
  300.         retString.resize(len);
  301.         uint i;
  302.         for (i = 0; i < len; i++)
  303.           retString[i] = (char)buf[i];
  304.   #endif
  305. # else
  306.         retString.resize(len);
  307.         uint i = 0;
  308.         for (cnt = len; cnt--; retString[i++] = (char)*resData++)
  309.           ;
  310. # endif
  311. #endif
  312.       }
  313.       UnlockResource(glbHdl);
  314.     }
  315.     FreeResource(glbHdl);
  316.     if (len)
  317.       return retString;
  318.   }
  319.  
  320.   if (::Module != this)                   // look in OWL module if different
  321.     return ::Module->LoadString(id);
  322.  
  323.   return retString;    // empty if string not found
  324. }
  325.  
  326. //----------------------------------------------------------------------------
  327.  
  328. //
  329. // Obsolete error handler--use Error(xmsg&,...) instead
  330. //
  331. #if defined(OWL1_COMPAT)
  332. void
  333. TModule::Error(int errorCode)
  334. {
  335.   char       errorStr[51];
  336.   TModule*   module = GetApplicationObject();
  337.  
  338.   sprintf(errorStr,
  339.            "Error received: error code = %d\nOK to proceed?",
  340.            errorCode);
  341.  
  342.   if (::MessageBox(0, errorStr, module ? module->GetName() : Name,
  343.                    MB_ICONSTOP | MB_YESNO | MB_TASKMODAL) == IDNO)
  344. #if defined(BI_PLAT_WIN32)
  345.   ::PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
  346. #else
  347.   ::PostAppMessage(GetCurrentTask(), WM_QUIT, 0, 0);
  348. #endif
  349. }
  350. #endif
  351.  
  352. //----------------------------------------------------------------------------
  353. // Module entry dynamic binding base class
  354.  
  355. //
  356. // Construct a Module entry object from a function name string or ordinal
  357. //
  358. TModuleProc::TModuleProc(const TModule& module, const char far* id)
  359. {
  360.   Proc = module.GetProcAddress(id);
  361.   if (!Proc) {
  362.     string msg;
  363.     if (HiUint16(uint32(id)) != 0)
  364.       msg = TXOwl::MakeMessage(IDS_INVALIDMODULEFCN, id);
  365.     else
  366.       msg = TXOwl::MakeMessage(IDS_INVALIDMODULEORD, LoUint16(uint32(id)));
  367.     msg += module.GetName();  // Just tack on the module name...
  368.     TXOwl::Raise(msg);
  369.   }
  370. }
  371.  
  372.  
  373. //----------------------------------------------------------------------------
  374. // Wrappers for Windows API
  375. //
  376. #if defined(BI_PLAT_WIN32)
  377.   static const char userStr[] = "USER32";
  378. # if defined(UNICODE)
  379.     static const char LoadIconStr[] = "LoadIconW";
  380.     static const char GetClassInfoStr[] = "GetClassInfoW";
  381.     static const char GetMenuStringStr[]= "GetMenuStringW";
  382. # else
  383.     static const char LoadIconStr[] = "LoadIconA";
  384.     static const char GetClassInfoStr[] = "GetClassInfoA";
  385.     static const char GetMenuStringStr[]= "GetMenuStringA";
  386. # endif
  387. #elif defined(BI_PLAT_WIN16)
  388.   static const char userStr[] = "USER";
  389.   static const char LoadIconStr[] = "LoadIcon";
  390.   static const char GetClassInfoStr[] = "GetClassInfo";
  391.   static const char GetMenuStringStr[] = "GetMenuString";
  392. #endif
  393. static const char GetMenuStateStr[] = "GetMenuState";
  394. static const char DestroyIconStr[] = "DestroyIcon";
  395.  
  396. //
  397. // Returns TModule object wrapping the handle of the USER module
  398. //
  399. TModule&
  400. TUser::GetModule()
  401. {
  402.   static TModule userModule(0, ::GetModuleHandle(userStr));
  403.   return userModule;
  404. }
  405.  
  406. //
  407. // Invokes 'LoadIcon' indirectly
  408. //
  409. HICON
  410. TUser::LoadIcon(HINSTANCE p1, LPCTSTR p2)
  411. {
  412.   static TModuleProc2<HICON, HINSTANCE, LPCTSTR>
  413.          loadIcon(GetModule(), LoadIconStr);
  414.   return loadIcon(p1, p2);
  415. }
  416.  
  417. //
  418. // Invokes 'DestroyIcon' indirectly
  419. //
  420. BOOL
  421. TUser::DestroyIcon(HICON p1)
  422. {
  423.   static TModuleProc1<BOOL, HICON> destroyIcon(GetModule(), DestroyIconStr);
  424.   return destroyIcon(p1);
  425. }
  426.  
  427. //
  428. // Invokes 'GetClassInfo' indirectly
  429. //
  430. BOOL
  431. TUser::GetClassInfo(HINSTANCE p1, LPCTSTR p2, LPWNDCLASS p3)
  432. {
  433.   static TModuleProc3<BOOL, HINSTANCE, LPCTSTR, LPWNDCLASS>
  434.          getClassInfo(GetModule(), GetClassInfoStr);
  435.   return getClassInfo(p1, p2, p3);
  436. }
  437.  
  438. //
  439. // Invokes 'GetMenuString' indirectly
  440. //
  441. int
  442. TUser::GetMenuString(HMENU p1, UINT p2, LPTSTR p3, int p4, UINT p5)
  443. {
  444.   static TModuleProc5<int, HMENU, uint, LPTSTR, int, int>
  445.          getMenuString(GetModule(), GetMenuStringStr);
  446.   return getMenuString(p1, p2, p3, p4, p5);
  447. }
  448.  
  449. //
  450. // Invokes 'GetMenuState' indirectly
  451. //
  452. UINT
  453. TUser::GetMenuState(HMENU p1, UINT p2, UINT p3)
  454. {
  455.   static TModuleProc3<UINT, HMENU, UINT, UINT>
  456.          getMenuState(GetModule(), GetMenuStateStr);
  457.   return getMenuState(p1, p2, p3);
  458. }
  459.  
  460.  
  461. //----------------------------------------------------------------------------
  462. //
  463. // Exception class
  464. //
  465.  
  466. //
  467. // Create the Invalid Module exception.
  468. //
  469. TXInvalidModule::TXInvalidModule(const char far* name)
  470. :
  471.   TXOwl(MakeMessage(IDS_INVALIDMODULE, name))
  472. {
  473. }
  474.  
  475. //
  476. // Creates a copy of exception for 16-bit Windows.
  477. //
  478. #if defined(BI_NO_COVAR_RET)
  479. TXBase*
  480. #else
  481. TXInvalidModule*
  482. #endif
  483. TXInvalidModule::Clone()
  484. {
  485.   return new TXInvalidModule(*this);
  486. }
  487.  
  488. //
  489. // Throw the exception
  490. //
  491. void
  492. TXInvalidModule::Throw()
  493. {
  494.   THROW( *this );
  495. }
  496.  
  497. //
  498. // Throw the exception
  499. //
  500. void
  501. TXInvalidModule::Raise(const char far* name)
  502. {
  503.   TXInvalidModule(name).Throw();
  504. }
  505.  
  506. #endif
  507. #if !defined(SECTION) || SECTION == 2
  508.  
  509. //----------------------------------------------------------------------------
  510. // TModule streaming
  511. //
  512.  
  513. IMPLEMENT_STREAMABLE(TModule);
  514.  
  515. #if !defined(BI_NO_OBJ_STREAMING)
  516.  
  517. //
  518. // Extract the module object from the persistent stream.
  519. //
  520. void*
  521. TModule::Streamer::Read(ipstream& is, uint32 /*version*/) const
  522. {
  523.   TModule* o = GetObject();
  524.   is >> (TResId&)o->Name;
  525. #if defined(OWL1_COMPAT)
  526.   is >> (TResId&)o->lpCmdLine;
  527. #endif
  528.   is >> o->ShouldFree;
  529.   if (o->ShouldFree)
  530.     o->Handle = ::LoadLibrary(o->Name);
  531.  
  532.   return o;
  533. }
  534.  
  535. //
  536. // Write the module into a persistent stream.
  537. //
  538. void
  539. TModule::Streamer::Write(opstream& os) const
  540. {
  541.   TModule* o = GetObject();
  542.   os << TResId(o->Name);
  543. #if defined(OWL1_COMPAT)
  544.   os << TResId(o->lpCmdLine);
  545. #endif
  546.   os << o->ShouldFree;
  547. }
  548.  
  549. #endif  // if !defined(BI_NO_OBJ_STREAMING)
  550.  
  551. #endif
  552. #if !defined(SECTION) || SECTION == 3
  553.  
  554. //----------------------------------------------------------------------------
  555. //
  556. // Entry (& exit) functions for Owl in a DLL
  557. //
  558.  
  559. #if defined(_BUILDOWLDLL)
  560.  
  561. //
  562. // TModule derived class to facilitate streaming pointer to the OWL Library
  563. // the OWL module must be streamed by reference before any pointers to it
  564. // the following code simply prevents writing data back over the OWL module
  565. //
  566.  
  567. class _OWLCLASS TObjectWindowsLibrary : public TModule {
  568.  public:
  569.   TObjectWindowsLibrary(HINSTANCE hInst) : TModule("ObjectWindowsDLL", hInst){}
  570.   DECLARE_STREAMABLE(_OWLCLASS, TObjectWindowsLibrary, 1);
  571. };
  572.  
  573. IMPLEMENT_STREAMABLE1(TObjectWindowsLibrary, TModule);
  574.  
  575. #if !defined(BI_NO_OBJ_STREAMING)
  576.  
  577. //
  578. // Read the object from the persistent stream.
  579. //
  580. void*
  581. TObjectWindowsLibrary::Streamer::Read(ipstream&, uint32) const
  582. {
  583.   return GetObject();
  584. }
  585.  
  586. //
  587. // Write the object into a persistent stream.
  588. //
  589. void
  590. TObjectWindowsLibrary::Streamer::Write(opstream&) const
  591. {
  592. }
  593.  
  594. #endif  // if !defined(BI_NO_OBJ_STREAMING)
  595.  
  596. //
  597. // Global pointer to this module
  598. //
  599. #if defined(BI_NAMESPACE)
  600. namespace OWL {
  601. #endif
  602.  
  603. TModule* Module = 0;
  604.  
  605. #if defined(BI_NAMESPACE)
  606. } // namespace OWL
  607. #endif
  608.  
  609. #if defined(BI_PLAT_WIN32)
  610.  
  611. static int  Attaches = 0;  // Win32s doesn't have per-instance data-- keep
  612.                            // track of number of attached processes
  613.  
  614. int WINAPI
  615. DllEntryPoint(HINSTANCE hInstance, uint32 reason, void*)
  616. {
  617.   switch (reason) {
  618.     case DLL_PROCESS_ATTACH: {
  619.       if (!Attaches) {
  620.         ::Module = new TObjectWindowsLibrary(hInstance);
  621.       }
  622.       Attaches++;
  623.       break;
  624.     }
  625.     case DLL_PROCESS_DETACH: {
  626.       Attaches--;
  627.       if (!Attaches)
  628.         delete ::Module;
  629.       break;
  630.     }
  631.   }
  632.   return true;
  633. }
  634.  
  635. #else  // !defined(BI_PLAT_WIN32)
  636.  
  637. static char BidsDllName[] = BIDS_DLLNAME ".DLL";
  638. static HINSTANCE BidsInst = 0;
  639.  
  640. // Add extra ref. counts on BIDS DLL since 16-bit Windows may (does) unload
  641. // DLLs in wrong order causing a crash at shutdown.
  642. //
  643. // NOTE: We use priority 31 to come just before/after ctr/dtr of global
  644. //       objects (which are assigned a priorority of 32)
  645. //
  646. static void lockDlls()
  647. {
  648.   BidsInst = ::LoadLibrary(BidsDllName);  
  649. }
  650. #pragma startup lockDlls 31
  651.  
  652. // Remove extra ref. count on BIDS DLL
  653. //
  654. static void unlockDlls()
  655. {
  656.   if (BidsInst > HINSTANCE(HINSTANCE_ERROR))
  657.     ::FreeLibrary(BidsInst);
  658. }
  659. #pragma exit unlockDlls 31
  660.  
  661. //
  662. // Entry point for the Owl DLL itself
  663. //
  664. int FAR PASCAL
  665. LibMain(HINSTANCE   hInstance,
  666.         uint16    /*wDataSeg*/,
  667.         uint16    /*cbHeapSize*/,
  668.         char far* /*lpCmdLine*/)
  669. {
  670.   // Static object aliasing the ObjectWindows DLL
  671.   //
  672.   static TObjectWindowsLibrary OWLDLLModule(hInstance);
  673.   ::Module = &OWLDLLModule;
  674.  
  675.   return Module->Status == 0;
  676. }
  677.  
  678. int
  679. FAR PASCAL
  680. WEP(int /*bSystemExit*/)
  681. {
  682.   return 1;
  683. }
  684.  
  685.  
  686. #endif  // defined(BI_PLAT_WIN32)
  687. #endif  // defined(_BUILDOWLDLL)
  688. #endif  // SECTION == 3
  689.  
  690. #if !defined(SECTION) || SECTION == 4
  691.  
  692. #if defined(BI_NAMESPACE)
  693. namespace OWL {
  694. #endif
  695. //
  696. // Inserter for formated output of instance handle
  697. //
  698. ostream& _OWLFUNC
  699. operator <<(ostream& os, const TModule& m)
  700. {
  701.   return os << hex << uint(m.Handle);
  702. }
  703. #if defined(BI_NAMESPACE)
  704. } // namespace OWL
  705. #endif
  706.  
  707. #endif //section 4
  708.  
  709.